import QtQuick 2.5
import QtQuick.Controls 1.4
import QtLocation 5.6
import QtPositioning 5.5
import QtQuick.Controls 2.1
import "../controls"
import "../map"
import "../controls/helper.js" as Helper
import "../controls/constants.js" as UI


Item
{
    id: rootPage
    property int dragWidth: UI.LIST_ITEM_HEIGHT
    property int dragBottomSpace: UI.LIST_ITEM_MARGIN

    property variant map
    property variant minimap
    property variant parameters

        //defaults
        //! [routecoordinate]
    property variant fromCoordinate: QtPositioning.coordinate()
    property variant toCoordinate: QtPositioning.coordinate(59.9645, 10.671)
    //! [routecoordinate]

    function createMap(provider)
    {
        var plugin

        if (parameters && parameters.length>0)
            plugin = Qt.createQmlObject ('import QtLocation 5.6;Plugin{ name:"' + provider + '"; parameters: rootPage.parameters} ', rootPage)
        else
            plugin = Qt.createQmlObject ('import QtLocation 5.6;Plugin{ name:"' + provider + '"} ', rootPage)

        if (map) {
            map.destroy()
            minimap = null
        }

        map = mapComponent.createObject(mapArea);
        map.plugin = plugin;
        map.zoomLevel = (map.maximumZoomLevel - map.minimumZoomLevel)/2
        map.parent = mapArea
        //map.anchors.fill = parent
    }

    function getPlugins()
    {
        var plugin = Qt.createQmlObject ('import QtLocation 5.6; Plugin {}', rootPage)
        var myArray = [];
        for (var i = 0; i<plugin.availableServiceProviders.length; i++) {
            var tempPlugin = Qt.createQmlObject ('import QtLocation 5.6; Plugin {name: "' + plugin.availableServiceProviders[i]+ '"}', rootPage)
            if (tempPlugin.supportsMapping())
                myArray.push(tempPlugin.name)
        }
        console.log("totally : " + myArray)
        return myArray.sort()
        //return myArray
    }

    function initializeProviders(pluginParameters)
    {
        var parameters = [];
        for (var prop in pluginParameters){
            var parameter = Qt.createQmlObject('import QtLocation 5.6; PluginParameter{ name: "'+ prop + '"; value: "' + pluginParameters[prop]+'"}',rootPage)
            parameters.push(parameter)
        }
        rootPage.parameters = parameters
        var plugins = getPlugins()
        mapMenu.createProvider(plugins)
    }

    function setLanguage(lang)
    {
        map.plugin.locales = lang;
        pageStack.pop()
        /////---------stackView.pop(page)
    }

    function selectProvider( providerName) {
        ///------------stackView.pop()
//        for (var i = 0; i < providerMenu.items.length; i++) {
//            providerMenu.items[i].checked = providerMenu.items[i].text === providerName
//        }
        if (minimap) {
            minimap.destroy()
            minimap = null
        }

        createMap(providerName)
        if (map.error === Map.NoError) {
            selectMapType(map.activeMapType)
            mapMenu.createTypeMenu(map)
            mapMenu.createToolMenu(map);
        } else {
            mapMenu.typelist = []
            //mapTypeMenu.clear();
            mapMenu.toollist = []
            //toolsMenu.clear();
        }
        root.state = 'showmap'
    }

    function selectMapType(mapType) {
        //stackView.pop(page)
//        for (var i = 0; i < mapTypeMenu.items.length; i++) {
//            mapTypeMenu.items[i].checked = mapTypeMenu.items[i].text === mapType.name
//        }
        map.activeMapType = mapType
        root.state = 'showmap'
    }

    function selectTool(tool)
    {
        switch (tool) {
        case "AddressRoute":
            pageStack.push("qrc:/qml/forms/RouteAddress.qml", { plugin: map.plugin,
                               toAddress: toAddress,
                               fromAddress: fromAddress})
            pageStack.currentItem.showRoute.connect(map.calculateCoordinateRoute)
            pageStack.currentItem.showMessage.connect(appWindow.showMessage)
            break
        case "CoordinateRoute":
            pageStack.push("qrc:/qml/forms/RouteCoordinate.qml", { toCoordinate: toCoordinate,
                               fromCoordinate: fromCoordinate})
            pageStack.currentItem.showRoute.connect(map.calculateCoordinateRoute)
            break
        case "Geocode":
            var geoCompo = Qt.createComponent("qrc:/qml/forms/Geocode.qml")
             if (geoCompo.status == Component.Ready)
             {
                 var page = geoCompo.createObject(appWindow);
                 page.showPlace.connect(map.geocode)
                 pageStack.push(page,  { address: fromAddress})
             }
            break
        case "RevGeocode":
            pageStack.push("qrc:/qml/forms/ReverseGeocode.qml",{ coordinate: fromCoordinate})
            pageStack.currentItem.showPlace.connect(map.geocode)
            break
        case "Language":
            pageStack.push("qrc:/qml/forms/Locale.qml",{ locale:  map.plugin.locales[0]})
            pageStack.currentItem.selectLanguage.connect(setLanguage)
            break
        default:
            console.log("Unsupported operation")
        }
        console.log("selected tool: ", tool)
        root.state = 'showmap'
    }



    Address {
        id :fromAddress
        street: "Sandakerveien 116"
        city: "Oslo"
        country: "Norway"
        state : ""
        postalCode: "0484"
    }
    //! [geocode0]

    Address {
        id: toAddress
        street: "Holmenkollveien 140"
        city: "Oslo"
        country: "Norway"
        postalCode: "0791"
    }

    Item
    {
        id: root
        anchors.fill: parent
        property  bool isShowMenu:false




//        Column
//        {
//            x: root.x
//            y: root.y
//            width: root.width
//            height: root.height
            Rectangle {
                id: mapArea
//                x: root.x
//                y: root.y
//                width: root.width
//                height: root.height - dragWidth
                anchors.fill: parent
                //anchors.top: parent.top
                anchors.bottomMargin: dragWidth
                //y: 0
                //height: parent.height - dragWidth
                color: "green"
            }

            state: 'showmap'
            states:
            [
                State
                {
                    name: 'showmenu'
                    //when: isShowMenu
                     PropertyChanges {target: dragArea; color: "#800000"}
                    PropertyChanges {target: menuArea;height: root.height/2}
                    PropertyChanges {target: mapArea; anchors.bottomMargin: root.height/2}
                },
                State
                {
                    name:'showmap'
                    //when: !isShowMenu
                    PropertyChanges {target: dragArea; color: "red"}
                    PropertyChanges {target: menuArea; height: dragWidth}
                    PropertyChanges {target: mapArea; anchors.bottomMargin: dragWidth}

                },
                State
                {
                    name:'menufullscreen'
                    //when: !isShowMenu
                    PropertyChanges {target: dragArea; color: "red"}
                    PropertyChanges {target: menuArea; height: root.height - 10}
                    PropertyChanges {target: mapArea; anchors.bottomMargin: root.height - 10}

                }
            ]

            Transition {
                from: "showmap"
                to: "showmenu"
                reversible: true
                ParallelAnimation
                {
                    id: pAnim;
                    NumberAnimation {
                        targets: [menuArea, mapArea]
                        properties: "y, height"
                        duration: 1000
                        easing.type: Easing.InOutQuad
                    }
                }

            }




            Rectangle {
                //color: "gray"

                id: menuArea
                anchors.bottom: parent.bottom
                width: parent.width
                height: root.height - mapArea.height
//                anchors.fill: parent
//                anchors.topMargin: root.height - dragWidth
                //anchors.top: mapArea.bottom
                //height: dragWidth
                //property  var  rect: {0;0; menuArea.width; 100}




                Rectangle
                {
                    id: dragArea
                    anchors.top: menuArea.top
                    anchors.topMargin: 20
                    width: menuArea.width
                    height: dragWidth
                    color: "red"
//                    Drag.active: mouseArea.drag.active
//                    Drag.hotSpot.x: 10
//                    Drag.hotSpot.y: 10
                    //Drag.keys:

                    MouseArea
                    {
                        id: mouseArea
                        anchors.fill: dragArea

                        //drag.proposedAction: Qt.TargetMoveAction
//                        drag.target: menuArea
//                        drag.axis: Drag.YAxis
                        //cursorShape: Qt.ArrowCursor

                    onDoubleClicked:
                    {
                        if(root.state == 'showmap')
                            root.state = 'showmenu'
                        else if(root.state == 'showmenu')
                            root.state = 'menufullscreen'
                        else
                            root.state = 'showmap'
                        console.log("current state: ", root.state)
                        //pageStack.push()
                    }


//                    onReleased:
//                    {
//                        dragArea.parent = menuArea
//                        dragArea.y = 0
//                    }

                }
                }

            ListInputItem
            {
                id: searchItem
                anchors.top: dragArea.bottom
                anchors.topMargin: 20
                height: 100
                visible: menuArea.height > dragWidth + dragBottomSpace
                lableTitle: qsTr("search")
            }


            SwipeMenu
            {
                id: mapMenu
                 anchors.top: searchItem.bottom
                 anchors.topMargin: 20
                //                anchors.fill: parent
                //                anchors.topMargin: dragArea.height
                tabVisible: menuArea.height > dragWidth + dragBottomSpace
                Component.onCompleted:
                {
                    mapMenu.selectProvider.connect(rootPage.selectProvider)
                    mapMenu.selectMapType.connect(rootPage.selectMapType)
                    mapMenu.selectTool.connect(rootPage.selectTool)
                }
            }

        }

        Dialog {
            id: mapPopListDlg

            property variant coordinate
            property int markersCount
            property int mapItemsCount

            //model:

            ListView
            {
                id: mapPopList
                anchors.fill: parent
                delegate: Item
                {
                    width: parent.width
                    height: 50
                    //var curIndex = selectedIndexs[0]
                    MouseArea
                    {
                        anchors.fill: parent
                        onClicked:
                        {
                            console.log(" model: " +model[index])
                            clickItem(model[index])
                            root.state = 'showmap'
                        }
                    }


                }
            }

            function update()
            {
                var array =
                ["addMarker", "getCoordinate", "fitViewport", "deleteMarkers", "deleteItems"]
                if (markersCount > 0) {
                   array.push("deleteMarkers")
                }

                if (mapItemsCount > 0) {
                    array.push("deleteItems")
                }
                mapPopList.model = array
            }

            function clickItem(item)
            {
                //stackView.pop(page)
                switch (item) {
                case "addMarker":
                    map.addMarker()
                    break
                case "getCoordinate":
                    map.coordinatesCaptured(coordinate.latitude, coordinate.longitude)
                    break
                case "fitViewport":
                    map.fitViewportToMapItems()
                    break
                case "deleteMarkers":
                    map.deleteMarkers()
                    break
                case "deleteItems":
                    map.deleteMapItems()
                    break
                default:
                    console.log("Unsupported operation")
                }
            }



        //            Component.onCompleted:
        //            {
        //                update()
        //            }

            function popUp(coordinate)
            {
                //stackView.pop(page)
                mapPopList.coordinate = coordinate
                mapPopList.markersCount = map.markers.length
                mapPopList.mapItemsCount = map.mapItems.length
                update()
                mapPopList.show()
            }
        }

        Dialog
        {
            id: markerPopupListDlg
            property int currentMarker
            property int markersCount
            signal itemClicked(string item)

            function update() {
                var array = ["deleteMarker", "getMarkerCoordinate", "moveMarkerTo"]
                if (currentMarker == markersCount-2)
                {
                    array.push("routeToNextPoint")
                    array.push("distanceToNextPoint")
                }
                if (currentMarker < markersCount-2)
                {
                    array.push("routeToNextPoints")
                    array.push("distanceToNextPoint")
                }

                array.push("draw")
                markerPopupList.model = array
            }

            function popUp(coordinate)
            {
                //stackView.pop(page)
                markerPopupList.markersCount = map.markers.length
                markerPopupList.update()
                markerPopupList.show()
            }

            function askForCoordinate()
            {
                pageStack.push("qrc:/qml/forms/ReverseGeocode.qml",  {title: qsTr("New Coordinate"),
                                   coordinate:   map.markers[map.currentMarker].coordinate})
                //                stackView.push({ item: Qt.resolvedUrl("forms/ReverseGeocode.qml") ,
                //                                   properties: { "title": qsTr("New Coordinate"),
                //                                       "coordinate":   map.markers[map.currentMarker].coordinate}})
                pageStack.currentItem.showPlace.connect(moveMarker)
                //stackView.currentItem.closeForm.connect(stackView.closeForm)
            }

            function moveMarker(coordinate)
            {
                map.markers[map.currentMarker].coordinate = coordinate;
                map.center = coordinate;
                //stackView.pop(page)
            }

            function clickItem(item)
            {
                //stackView.pop(page)
                switch (item) {
                case "deleteMarker":
                    map.deleteMarker(map.currentMarker)
                    break;
                case "getMarkerCoordinate":
                    map.coordinatesCaptured(map.markers[map.currentMarker].coordinate.latitude, map.markers[map.currentMarker].coordinate.longitude)
                    break;
                case "moveMarkerTo":
                    askForCoordinate()
                    break;
                case "routeToNextPoint":
                case "routeToNextPoints":
                    map.calculateMarkerRoute()
                    break
                case "distanceToNextPoint":
                    var coordinate1 = map.markers[currentMarker].coordinate;
                    var coordinate2 = map.markers[currentMarker+1].coordinate;
                    var distance = Helper.formatDistance(coordinate1.distanceTo(coordinate2));
                    appWindow.showMessage(qsTr("Distance"),"<b>" + qsTr("Distance:") + "</b> " + distance)
                    break
                case "draw":
                    drawPopList.popUp()
                    break
                default:
                    console.log("Unsupported operation")
                }
            }

            ListView
            {
                id: markerPopupList
                anchors.fill: parent
                delegate: Item
                {
                    width: parent.width
                    height: 50
                    //var curIndex = selectedIndexs[0]
                    MouseArea
                    {
                        anchors.fill: parent
                        onClicked:
                        {
                            console.log(" model: " +model[index])
                            clickItem(model[index])
                            root.state = 'showmap'
                        }
                    }


                }
            }

        }

        Dialog
        {
            id: drawPopListDlg
            signal itemClicked(string item)

            ListView
            {
                id: drawPopList
                anchors.fill: parent
                delegate: Item
                {
                    width: parent.width
                    height: 50
                    //var curIndex = selectedIndexs[0]
                    MouseArea
                    {
                        anchors.fill: parent
                        onClicked:
                        {
                            console.log(" model: " +model[index])
                            clickItem(model[index])
                            root.state = 'showmap'
                        }
                    }
                }
            }


            function update() {
                var array = ["drawImage"]
                if (markerPopupList.currentMarker <= markerPopupList.markersCount-2)
                {
                    array.push("drawRectangle")
                    array.push("drawCircle")
                    array.push("drawPolyline")
                }
                if (markerPopupList.currentMarker < markerPopupList.markersCount-2)
                {
                    array.push("drawPolygonMenu")
                }
                drawPopList.model = array
            }

            function popUp(coordinate)
            {
                //stackView.pop(page)
                //markerPopupList.markersCount = map.markers.length
                drawPopList.update()
                drawPopList.show()
            }

            function clickItem(item)
            {
                switch(item)
                {
                case "drawImage":
                    map.addGeoItem("ImageItem")
                    break
                case "drawRectangle":
                    map.addGeoItem("RectangleItem")
                    break
                case "drawCircle":
                    map.addGeoItem("CircleItem")
                    break;
                case "drawPolyline":
                    map.addGeoItem("PolylineItem")
                    break;
                case "drawPolygonMenu":
                    map.addGeoItem("PolygonItem")
                    break
                default:
                    console.log("Unsupported operation")
                }
            }

        }

        Dialog
        {
            id: itemPopListDlg

            property variant type
            signal itemClicked(string item)

            ListView
            {
                id: itemPopList
                anchors.fill: parent
                delegate: Item
                {
                    width: parent.width
                    height: 50
                    //var curIndex = selectedIndexs[0]
                    MouseArea
                    {
                        anchors.fill: parent
                        onClicked:
                        {
                            console.log(" model: " +model[index])
                            clickItem(model[index])
                            root.state = 'showmap'
                        }
                    }
                }
            }

            function popUp(type,coordinate)
            {
                itemPopList.type = type
                itemPopList.update()

                itemPopList.show()
            }

            function update()
            {
                var array = ["show" + type + "Info", "delete" + type]
                itemPopList.model = array
            }
            function clickItem(item)
            {
                switch (item) {
                case "showRouteInfo":
                    appWindow.showRouteListPage()
                    break;
                case "deleteRoute":
                    map.routeModel.reset();
                    break;
                case "showPointInfo":
                    map.showGeocodeInfo()
                    break;
                case "deletePoint":
                    map.geocodeModel.reset()
                    break;
                default:
                    console.log("Unsupported operation")
                }
            }
        }
    }


        Component {
            id: mapComponent

            MapComponent{
//                width: page.width
//                height: page.height
                anchors.fill: parent
                onFollowmeChanged: mapMenu.isFollowMe = followme
                onSupportedMapTypesChanged: mapMenu.createTypeMenu(map)
                onCoordinatesCaptured: {
                    var text = "<b>" + qsTr("Latitude:") + "</b> " + Helper.roundNumber(latitude,4) + "<br/><b>" + qsTr("Longitude:") + "</b> " + Helper.roundNumber(longitude,4)
                    pageStack.showMessage(qsTr("Coordinates"),text);
                }
                onGeocodeFinished:{
                    if (map.geocodeModel.status == GeocodeModel.Ready) {
                        if (map.geocodeModel.count == 0) {
                            pageStack.showMessage(qsTr("Geocode Error"),qsTr("Unsuccessful geocode"))
                        } else if (map.geocodeModel.count > 1) {
                            pageStack.showMessage(qsTr("Ambiguous geocode"), map.geocodeModel.count + " " +
                                                  qsTr("results found for the given address, please specify location"))
                        } else {
                            pageStack.showMessage(qsTr("Location"), geocodeMessage())
                        }
                    } else if (map.geocodeModel.status == GeocodeModel.Error) {
                        pageStack.showMessage(qsTr("Geocode Error"),qsTr("Unsuccessful geocode"))
                    }
                }
                onRouteError: pageStack.showMessage(qsTr("Route Error"),qsTr("Unable to find a route for the given points"))

                onShowGeocodeInfo: pageStack.showMessage(qsTr("Location"),geocodeMessage())

                onErrorChanged: {
                    if (map.error != Map.NoError) {
                        var title = qsTr("ProviderError")
                        var message =  map.errorString + "<br/><br/><b>" + qsTr("Try to select other provider") + "</b>"
                        if (map.error == Map.MissingRequiredParameterError)
                        message += "<br/>" + qsTr("or see") + " \'mapviewer --help\' "
                        + qsTr("how to pass plugin parameters.")
                        pageStack.showMessage(title,message);
                    }
                }
                onShowMainMenu: mapPopList.popUp(coordinate)

                onShowMarkerMenu: markerPopupList.popUp(coordinate)

                onShowRouteMenu: itemPopList.popUp("Route",coordinate)
                onShowPointMenu: itemPopList.popUp("Point",coordinate)
                onShowRouteList: pageStack.showRouteListPage()
            }
        }

}
